home *** CD-ROM | disk | FTP | other *** search
/ Apple II Magazines (PO) / Nibble Volume 09, No. 04 (1988-04)(MicroSPARC)(Side A).zip / Nibble Volume 09, No. 04 (1988-04)(MicroSPARC)(Side A).po / DISK.EJECTOR.S < prev    next >
Text File  |  1996-12-24  |  19KB  |  344 lines

  1.              1 ******************************
  2.              2 *                            *
  3.              3 *   DISK EJECTER FOR APPLE   *
  4.              4 *    3.5 INCH DISK DRIVES.   *
  5.              5 *                            *
  6.              6 *    Syntax:  CALL EJ,S,D    *
  7.              7 *                            *
  8.              8 *    EJ= ADDRESS OF ROUTINE  *
  9.              9 *    S = SLOT # (1-7)        *
  10.             10 *    D = DRIVE # (1-127)     *
  11.             11 *    BOTH MUST BE GIVEN!!!!! *
  12.             12 *                            *
  13.             13 *       BY Tim Swihart       *
  14.             14 *                            *
  15.             15 *     COPYRIGHT (C) 1987     *
  16.             16 *     by MicroSPARC, INC.    *
  17.             17 *     Concord, MA  01742     *
  18.             18 *                            *
  19.             19 *      MERLIN PRO V2.54      *
  20.             20 *                            *
  21.             21 ******************************
  22.             22 *
  23.             23          ORG   $8000
  24.             24 *
  25.             25 CsFF     EQU   $C0FF      ;Address of requested slot
  26.             26 *                          (rewritten during execution)
  27.             27 CHKCOM   EQU   $DEBE      ;Checks for comma
  28.             28 FRMNUM   EQU   $DD67      ;Evaluates passed formula
  29.             29 GETADR   EQU   $E752      ;Converts # in FAC to an integer
  30.             30 LINNUM   EQU   $0050      ;Lo-byte of integer from GETADR
  31.             31 DRIVE    EQU   $00FA      ;Storage for requested drive #
  32.             32 SLOT     EQU   $00FB      ;Stores address for slot #
  33.             33 US       EQU   $00FD      ;Stores address for start of
  34.             34 *                          this routine
  35.             35 REWRIT   EQU   $0000      ;This value will be rewritten
  36.             36 *                          during execution
  37.             37 USERERR  EQU   $00FF      ;Store error code here when done
  38.             38 CMD      EQU   $00        ;0 = Status, 4 = Control
  39.             39 DRV      EQU   $00        ;Smartport drive #
  40.             40 SUBCMD   EQU   $00        ;3 = Request DIB
  41.             41 SIZE     EQU   $00        ;Number of bytes in CTL
  42.             42 TYPE     EQU   $00        ;Type = $01 for 3.5" disk
  43.             43 *
  44.             44 * SPECIAL ERROR CODES
  45.             45 BADDRIV  EQU   $CA        ;Requested drive NOT a 3.5"
  46.             46 BADSLOT  EQU   $CB        ;Requested slot higher than 7
  47.             47 BADCARD  EQU   $CC        ;Requested slot not a Smartport
  48.             48 *
  49.             49 * Any line beginning with the label 'Pxx' (where xx is
  50.             50 * a number) MUST be present when you assemble this program.
  51.             51 * These labels are used to determine offsets that are
  52.             52 * REQUIRED for this program to work properly.
  53.             53 *
  54.             54 *
  55.             55 * First, we buffer off the address where this routine
  56.             56 * is currently located and store it at 'US'.  If you want
  57.             57 * to modify this routine to work from a language other
  58.             58 * than APPLESOFT, then you will have to replace the next
  59.             59 * four lines of code with a different method for deter-
  60.             60 * mining where this routine starts in memory.
  61.             61 *
  62.             62 START    LDA   $50        ;Lo-byte of where routine starts
  63.             63          STA   US         ;Buffer it to $00FE
  64.             64          LDA   $51        ;Hi-byte of where routine starts
  65.             65          STA   US+1       ;Buffer it to $00FF
  66.             66 *
  67.             67 *
  68.             68 * The starting address is needed so that this routine can
  69.             69 * use zero-page indexed addressing to access portions of
  70.             70 * itself.  Since the last portion of this program is where
  71.             71 * the "self-referencing" is taking place, and since this
  72.             72 * routine is more than 255 bytes long (the upper limit for
  73.             73 * zero-paged indexed addressing is 255), we must adjust
  74.             74 * 'US'.  This makes sure that all of the upper portion of
  75.             75 * this routine can be accessed by means of zero-page
  76.             76 * indexed adressing.
  77.             77 *
  78.             78          CLC
  79.             79          LDA   US         ;Get lo-byte of 'US'
  80.             80          ADC   #PAS-START ;Add adjustment
  81.             81          STA   US         ;Save new lo-byte of 'US'
  82.             82          LDA   US+1       ;Get hi-byte of 'US'
  83.             83          ADC   #$00       ;Adjust hi-byte
  84.             84          STA   US+1       ;Save new hi-byte of 'US'
  85.             85 *
  86.             86 *
  87.             87 * Now eat the comma that lives between 'EJ' and 'S' in the
  88.             88 * user's 'CALL EJ,S,D' command.  If you want to use this
  89.             89 * routine with an ampersand handler that eats the comma for
  90.             90 * you, then either remove the following line or replace it
  91.             91 * with three NOP's.
  92.             92 *
  93.             93          JSR   CHKCOM     ;'SYNTAX ERROR' if no comma
  94.             94 *
  95.             95 *
  96.             96 * Evaluate the slot passed from the calling program.  Make
  97.             97 * sure that it is less than 8 (since the highest numbered
  98.             98 * slot is slot 7).  Returns with a 'SYNTAX ERROR' and puts
  99.             99 * a special error code into location $00FF if the slot
  100.            100 * number is higher than seven. If there is an syntax error
  101.            101 * in the expresion for d location $00FF contain
  102. :
  103. :         L 1 0 0 ,
  104.  
  105.            100 * number is higher than seven. If there is an syntax error
  106.            101 * in the expresion for 'S', then a 'SYNTAX ERROR' is
  107.            102 * returned and location $00FF contains garbage left by
  108.            103 * another routine.
  109.            104 *
  110.            105          JSR   FRMNUM     ;Evaluate 'S'
  111.            106          JSR   GETADR     ;Convert it to an integer and
  112.            107 *                          store at locations $50 and $51
  113.            108          LDA   LINNUM     ;Get lo-byte from $50
  114.            109          CMP   #$08       ;Is slot between 0 and 7?
  115.            110          BCC   CONT       ;Yes, so continue
  116.            111          LDA   #BADSLOT   ;No, so prepare special error
  117.            112          STA   USERERR    ;Save it for the user
  118.            113          RTS              ;Return to calling program
  119.            114 CONT     ADC   #$C0       ;Prepare '$Cs' where 's' is slot
  120.            115          STA   SLOT+1     ;Store as hi-byte of 'SLOT'
  121.            116          LDA   #$00       ;Prepare lo-byte of 'SLOT'
  122.            117          STA   SLOT       ;'SLOT' now contains $Cs00
  123.            118 *
  124.            119 *
  125.            120 * Now eat the comma between 'S' and 'D' of the CALL from
  126.            121 * the user.
  127.            122 *
  128.            123          JSR   CHKCOM     ;'SYNTAX ERROR' if no comma
  129.            124 *
  130.            125 *
  131.            126 * Evaluate the drive number that the user passed to us.
  132.            127 * If there is a syntax error in the expression for 'D',
  133.            128 * then a 'SYNTAX ERROR' is returned and location $00FF
  134.            129 * contains garbage left by some other routine.
  135.            130 *
  136.            131          JSR   FRMNUM     ;Evaluate 'D'
  137.            132          JSR   GETADR     ;Convert it to an integer and
  138.            133 *                          store at locations $50 and $51
  139.            134          LDA   LINNUM     ;Get the lo-byte
  140.            135          STA   DRIVE      ;Save it for later
  141.            136 *
  142.            137 *
  143.            138 * Verify that the requested slot contains a Smartport.
  144.            139 * If not then return the special error code for 'BADCARD'.
  145.            140 *
  146.            141          LDY   #$01       ;First signature byte is at $Cs01
  147.            142          LDA   (SLOT),Y   ;Get signature byte #1
  148.            143          CMP   #$20       ;Is it correct?
  149.            144          BEQ   NEXT1      ;Yes, go check signature byte #2
  150.            145          LDA   #BADCARD   ;No, so prepare special error
  151.            146          STA   USERERR    ;Save it for the user
  152.            147          RTS              ;Return to calling program
  153.            148 NEXT1    LDY   #$03       ;Next signature byte is at $Cs03
  154.            149          LDA   (SLOT),Y   ;Get signature byte #2
  155.            150          CMP   #$00       ;Is it correct?
  156.            151          BEQ   NEXT2      ;Yes, go check signature byte #3
  157.            152          LDA   #BADCARD   ;No, so prepare special error
  158.            153          STA   USERERR    ;Save it for the user
  159.            154          RTS              ;Return to calling program
  160.            155 NEXT2    LDY   #$05       ;Next signature byte is at $Cs05
  161.            156          LDA   (SLOT),Y   ;Get signature byte #3
  162.            157          CMP   #$03       ;Is it correct?
  163.            158          BEQ   NEXT3      ;Yes, go check signature byte #4
  164.            159          LDA   #BADCARD   ;No, so prepare special error
  165.            160          STA   USERERR    ;Save it for the user
  166.            161          RTS              ;Return to calling program
  167.            162 NEXT3    LDY   #$07       ;Next signature byte is at $Cs07
  168.            163          LDA   (SLOT),Y   ;Get signature byte #4
  169.            164          CMP   #$00       ;Is it correct?
  170.            165          BEQ   PAS        ;Yes, so continue
  171.            166          LDA   #BADCARD   ;No, so prepare special error
  172.            167          STA   USERERR    ;Save it for the user
  173.            168          RTS              ;Return to calling program
  174.            169 *
  175.            170 *
  176.            171 * Now that we know we're talking to a Smartport, we need
  177.            172 * to set up the command table to talk to the drive so
  178.            173 * that we can verify it is a 3.5" drive.  To do this, we
  179.            174 * need to calculate the Smartport entry point.  This is
  180.            175 * always three more than the Prodos entry point.  The
  181.            176 * Prodos entry point is found by adding the value in $CsFF
  182.            177 * to $Cs00.
  183.            178 *
  184.            179 PAS      LDY   #$FF       ;Prepare to get byte at $CsFF
  185.            180          LDA   (SLOT),Y   ;Get value at $CsFF
  186.            181          CLC
  187.            182          ADC   #$03       ;Add three to it
  188.            183          STA   SLOT       ;Save it in lo-byte of 'SLOT'
  189.            184 *
  190.            185 * Pay attention, things get tricky here. First, we modify
  191.            186 * the 'REWRIT' portion of 'JSR REWRIT'. (The accumulator
  192.            187 * already holds the lo-byte of the Smartport's entry
  193.            188 * point).
  194.            189 *
  195.            190          LDY   #DOIT-PAS+1 ;Offset to middle byte of
  196.            191 *                          'JSR REWRIT'
  197.            192          STA   (US),Y     ;Put lo-byte of Smartport entry
  198.            193 *                          point into 'JSR REWRIT'
  199.            194          LDA   SLOT+1     ;Get hi-byte of Smartport entry
  200.            195          INY              ;Adjust offset
  201.            196          STA   (US),Y     ;Put hi-byte of Smartport entry
  202.            197 *                          point into 'JSR REWRIT'
  203.            198 *
  204.            199 * Now, modify the address of the command list (CMDLIST).
  205.            200 *
  206.            201          LDA   US         ;Get lo-byte of this routine's
  207.            202 *                          starting address
  208.            203          LDY   #P3-PAS    ;Offset to pointer to CMDLIST
  209.            204          CLC
  210.            205          ADC   #CMDLIST-PAS ;Offset to CMDLIST itself
  211.            206          STA   (US),Y     ;CMDLIST pointer's lo-byte
  212.            207          LDA   US+1       ;Get ready to do hi-byte
  213.            208          ADC   #$00       ;Hi-byte of CMDLIST's pointer
  214.            209          INY              ;Adjust the offset
  215.            210          STA   (US),Y     ;CMDLIST pointer's hi-byte
  216.            211 *
  217.            212 * Now, we modify the address of the control list (CTL).
  218.            213 *
  219.            214          LDA   US         ;Get lo-byte of this routine's
  220.            215 *                          starting address
  221.            216          LDY   #P5-PAS    ;Offset to pointer to CTL
  222.            217          CLC
  223.            218          ADC   #CTL-PAS   ;Offset to CTL itself
  224.            219          STA   (US),Y     ;Rewrite CTL pointer's lo-byte
  225.            220          LDA   US+1       ;Get ready to do hi-byte
  226.            221          ADC   #$00       ;Hi-byte for CTL's pointer
  227.            222          INY              ;Adjust offset
  228.            223          STA   (US),Y     ;Rewrite CTL pointer's hi-byte
  229.            224 *
  230.            225 * Now, we modify the address portion of 'JSR DO_IT'.
  231.            226 *
  232.            227          LDY   #P1-PAS+1  ;Offset to middle byte of
  233.            228 *                          'JSR DO_IT'
  234.            229          LDA   US         ;Get lo-byte of this routine's
  235.            230 *                          starting address
  236.            231          CLC
  237.            232          ADC   #DOIT-PAS  ;Offset to 'JSR REWRIT'
  238.            233          STA   (US),Y     ;Rewrite lo-byte of address
  239.            234 *                          portion of 'JSR DO_IT'
  240.            235          LDA   US+1
  241.            236          ADC   #$00       ;Prepare hi-byte
  242.            237          INY              ;Adjust offset for hi-byte
  243.            238          STA   (US),Y     ;Rewrite hi-byte of address
  244.            239 *                          portion of 'JSR DO_IT'
  245.            240 *
  246.            241 *
  247.            242 * Things get a little easier now as we set up the drive #,
  248.            243 * command #, subcommand # and the size of the control list
  249.            244 * so that we can request the Device Information Block (DIB)
  250.            245 * from the drive the user sent.
  251.            246 *
  252.            247          LDA   DRIVE      ;Get the drive number
  253.            248          LDY   #P4-PAS    ;Offset to DRV in CMDLIST
  254.            249          STA   (US),Y     ;Rewrite the drive number
  255.            250 *
  256.            251          LDA   #$00       ;CMD = 0 for STATUS call
  257.            252          LDY   #P2-PAS    ;Offset to CMD
  258.            253          STA   (US),Y     ;Rewrite CMD
  259.            254 *
  260.            255          LDA   #$03       ;SUBCMD = 3 to request DIB
  261.            256          LDY   #P6-PAS    ;Offset to SUBCMD
  262.            257          STA   (US),Y     ;Rewrite SUBCMD
  263.            258 *
  264.            259 *
  265.            260 * Now get the DIB from the drive and make sure the drive
  266.            261 * is a 3.5" (Unidisk 3.5 or Apple 3.5).  If the drive is
  267.            262 * NOT a 3.5" drive, then a special error code is placed
  268.            263 * in location $00FF and control is returned to the
  269.            264 * calling program.  If the device does not exist, or some
  270.            265 * other error occurs, then that error is placed in
  271.            266 * location $00FF and control is returned to the calling
  272.            267 * program.
  273.            268 *
  274.            269 P1       JSR   DOIT       ;Gets DIB for us
  275.            270          BCC   WORKED     ;If no error then continue
  276.            271          STA   USERERR    ;Else save error
  277.            272          RTS              ;And go back to calling program
  278.            273 WORKED   LDY   #P7-PAS    ;Offset to device type in CTL
  279.            274          LDA   (US),Y     ;Gets TYPE from CTL
  280.            275          CMP   #$01       ;Is it a 3.5" drive?
  281.            276          BEQ   MORE       ;Yes, so keep going
  282.            277          LDA   #BADDRIV   ;No, so prepare special error
  283.            278          STA   USERERR    ;Save it for the user
  284.            279          RTS              ;Return to calling program
  285.            280 *
  286.            281 *
  287.            282 * Now, we have to change the command #, subcommand #,
  288.            283 * the size of the control list and make sure the first
  289.            284 * byte in the control list is zero.
  290.            285 *
  291.            286 MORE     LDA   #$04       ;CMD=4 for CONTROL call
  292.            287          LDY   #P2-PAS    ;Offset to CMD
  293.            288          STA   (US),Y     ;Rewrite CMD
  294.            289 *
  295.            290 * SUBCMD=4 for eject and accumulator already contains 4
  296.            291 *
  297.            292          LDY   #P6-PAS    ;Offset to SUBCMD
  298.            293          STA   (US),Y     ;Rewrite SUBCMD
  299.            294 *
  300.            295          LDA   #$00       ;Control list contains zero
  301.            296 *                          bytes for eject command
  302.            297          LDY   #CTL-PAS   ;Offset to SIZE in CTL
  303.            298          STA   (US),Y     ;Rewrite SIZE
  304.            299          INY              ;Adjust offset
  305.            300          STA   (US),Y     ;Make first byte in CTL equal 0
  306.            301 *
  307.            302 *
  308.            303 * Believe it or not, we're finally ready to eject the
  309.            304 * disk!!!  Whew, what a ride!!
  310.            305 *
  311.            306 DOIT     JSR   REWRIT     ;This line kicks the disk out!
  312.            307 P2       DB    CMD        ;0 for STATUS, 4 for CONTROL
  313.            308 P3       DA    CMDLIST    ;Address of the command list
  314.            309 *                          will be rewritten here
  315.            310          STA   USERERR    ;Save any error for the user
  316.            311 *                          A zero will be here if no error
  317.            312          RTS              ;FINISHED!!!!!!!!
  318.            313 *
  319.            314 *
  320.            315 * Here are the Command List (CMDLIST) and the Control
  321.            316 * List (CTL).
  322.            317 *
  323.            318 CMDLIST  DB    #$03       ;Number of items in CMDLIST
  324.            319 P4       DB    DRV        ;Drive # requested by user
  325.            320 P5       DA    CTL        ;Address of Control List
  326.            321 P6       DB    SUBCMD     ;Subcommand
  327.            322 CTL      DB    SIZE       ;Number of items in CTL if doing
  328.            323 *                          the eject.  Device Status Byte
  329.            324 *                          if doing the 'GET DSB'.
  330.            325 *
  331.            326 * Here are the other 24 bytes in the CTL.
  332.            327 *
  333.            328          DB    $00        ;Size (Lo-byte)
  334.            329          DB    $00        ;Size (Middle-byte)
  335.            330          DB    $00        ;Size (Hi-byte)
  336.            331          DB    $00        ;ID string length
  337.            332          DS    16,32      ;ID string (32='SPACE')
  338.            333 P7       DB    TYPE       ;Type byte for device
  339.            334          DB    $00        ;Subtype for device
  340.            335          DW    $0000      ;Version (word)
  341.            336 *
  342.            337 * That's it!
  343.            338 *
  344.